// 2010-03-17 - M. Caputo

#include <QString>
#include <QTextStream>
#include <QFile>

#include "OffScene.h"

OffScene::OffScene(const QString & fileName)
{
    parseFile(fileName);
}

void OffScene::parseFile(const QString & fileName)
{
    int vCount, pCount, eCount, rCount, i, j, k;
    QString str, temp;
    QFile data(fileName);
    QTextStream ifs(&data);
    // Check if the file is open
    if(!data.open(QIODevice::ReadOnly)) {
        throw QString(QObject::tr("File can not opened!"));
    }

    // Check if the file is an Off-File
    ifs >> str;
    if(str != "OFF") {
        throw QString(QObject::tr("File Format is not OFF!"));
    }
    // Readin vCount, pCount, eCount
    rCount = 0;
    while(rCount < 3) {
        str = ifs.readLine(0);
        str = str.simplified();
        for(i = 0; i < str.length();i++){
            if(str[i] == '#') {
                break;
            }
            else {
                for(rCount = 0; rCount < 3; rCount++) {
                    for(j = i; j < str.length(); j++) {
                        if(str[j] == ' ') {
                                        break;
                        }
                        temp[j-i] = str [j];
                    }
                    switch(rCount) {
                        case 0:
                            vCount = temp.toInt();
                            break;
                        case 1:
                            pCount = temp.toInt();
                            break;
                        case 2:
                            eCount = temp.toInt();
                            break;
                        default:
                            break;
                    }
                    i = j + 1;
                    temp = "";
                }
            }
        }
    }
    //Readin of Vertices
    rCount = 0;
    CVertex **vertices = new CVertex*[vCount];
    float x, y, z;
    while(rCount < vCount) {
        str = ifs.readLine(0);
        str = str.simplified();
        for(i = 0; i < str.length(); i++) {
            if(str[i] == '#') {
                break;
            }
            else {
                for(k = 0; k < 3; k++){
                    for(j = i; j < str.length(); j++) {
                        if(str[j] == ' ') {
                            break;
                        }
                        temp[j-i] = str [j];
                    }
                    switch(k){
                        case 0:
                            x = temp.toFloat();
                            break;
                        case 1:
                            y = temp.toFloat();
                            break;
                        case 2:
                            z = temp.toFloat();
                            break;
                        default:
                            break;
                    }
                    i = j +1 ;
                    temp = "";
                }
                if(i < str.length()) {
                    QColor* color = readcolor(str, i, j);
                    if(color != 0) {
                        vertices[rCount] = new CVertex(x,y,z,*color);
                        rCount++;
                    }
                    else {
                        vertices[rCount] = new CVertex(x, y, z);
                        rCount++;
                    }
                }
                else {
                    vertices[rCount] = new CVertex(x, y, z);
                    rCount++;
                }
            }
        }
    }
    //Readin of the Polygons
    rCount = 0;
    while(rCount < pCount) {
        str = ifs.readLine(0);
        str = str.simplified();
        for(i = 0; i < str.length(); i++) {
            if(str[i] == '#') {
                break;
            }
            else {
                int n;
                for(j = i; j < str.length(); j++) {
                    if(str[j] == ' ') {
                        break;
                    }
                    temp[j-i] = str [j];
                }
                n = temp.toInt();
                i = j + 1;
                temp = "";
                CPolygon polygon;
                for(k = 0; k < n; k++) {
                    for(j = i; j < str.length(); j++) {
                        if(str[j] == ' ') {
                            break;
                        }
                        temp[j-i] = str [j];
                    }
                    i = j + 1;
                    polygon.addVertex(*(vertices[temp.toInt()]));
                    i = j + 1;
                    temp = "";
                }
                if(i < str.length()) {
                    if(str[i] != '#') {
                        QColor* color = readcolor(str, i, j);
                        polygon.addColor(*color);
                    }
                }
                polygons.append(polygon);
                rCount++;
            }
        }
    }
    for(int i=0; i<vCount; i++) {
        delete vertices[i];
    }
    delete[] vertices;
    data.close();
}

int OffScene::polygonsCount()
{
    return polygons.size();
}

const CPolygon & OffScene::polygon(int i)
{
    return polygons[i];
}

QColor* OffScene::readcolor(QString str, int i, int j)
{
    QColor* color;
    if(str[i] != '#') {
        QString temp;
        for(int cCount = 0; cCount < 4; cCount++) {
            for(j = i; j < str.length(); j++) {
                if(str[j] == ' ') {
                    break;
                }
                temp[j-i] = str[j];
            }
            if(temp[1] == '.') {
                switch(cCount) {
                    case 0:
                        color->setRedF(temp.toFloat());
                        break;
                    case 1:
                        color->setGreenF(temp.toFloat());
                        break;
                    case 2:
                        color->setBlueF(temp.toFloat());
                        break;
                    case 3:
                        color->setAlphaF(temp.toFloat());
                        break;
                    default:
                        break;
                }
            } else {
                switch(cCount) {
                    case 0:
                        color->setRed(temp.toInt());
                        break;
                    case 1:
                        color->setGreen(temp.toInt());
                        break;
                    case 2:
                        color->setBlue(temp.toInt());
                        break;
                    case 3:
                        color->setAlpha(temp.toInt());
                        break;
                    default:
                        break;
                }
            }
            i = j + 1;
            temp = "";
        }
        return color;
    }
    return 0;
}
